/*
 * gui.c
 *
 *  Created on: Aug 9, 2020
 *      Author: LizoZheLin
 */
#include "gui.h"

unsigned short rgb24_2_rgb565(int r, int g, int b)   //应该会损失数据内容
{
        return (unsigned short)(((r << 8) & 0xF800) |
            ((g << 3) & 0x7E0)  |
            (b >> 3));
}

// Converts RGB to HSL

void RGBtoHSL(const COLOR_RGB *rgb, COLOR_HSL *hsl)
{
    float h=0, s=0, l=0;
    // normalizes red-green-blue values
    float r = rgb->red/255.f;
    float g = rgb->green/255.f;
    float b = rgb->blue/255.f;
    float maxVal = max3v(r, g, b);
    float minVal = min3v(r, g, b);


   // hue

   if(maxVal == minVal)
    {
       h = 0; // undefined
    }

   else if(maxVal==r && g>=b)
    {
       h = 60.0f*(g-b)/(maxVal-minVal);
    }

   else if(maxVal==r && g<b)
    {
       h = 60.0f*(g-b)/(maxVal-minVal) + 360.0f;
    }

   else if(maxVal==g)
    {
       h = 60.0f*(b-r)/(maxVal-minVal) + 120.0f;
    }
    else if(maxVal==b)
    {
       h = 60.0f*(r-g)/(maxVal-minVal) + 240.0f;
    }

   // luminance

   l = (maxVal+minVal)/2.0f;
    // saturation

   if(l == 0 || maxVal == minVal)
    {
       s = 0;
    }

   else if(0<l && l<=0.5f)
    {
       s = (maxVal-minVal)/(maxVal+minVal);
    }
    else if(l>0.5f)
    {
       s = (maxVal-minVal)/(2 - (maxVal+minVal)); //(maxVal-minVal > 0)?
    }
   hsl->hue = (h>360)? 360 : ((h<0)?0:h);
   hsl->saturation = ((s>1)? 1 : ((s<0)?0:s))*100;
   hsl->luminance = ((l>1)? 1 : ((l<0)?0:l))*100;
}
// Converts HSL to RGB

void HSLtoRGB(const COLOR_HSL *hsl, COLOR_RGB *rgb)
{
    float h = hsl->hue;                 // h must be [0, 360]
    float s = hsl->saturation/100; // s must be [0, 1]
    float l = hsl->luminance/100;     // l must be [0, 1]
    float R, G, B;
    if(hsl->saturation == 0)
    {
	   // achromatic color (gray scale)
    	R = G = B = l*255.f;
    }
	else
	{
	   float q = (l<0.5f)?(l * (1.0f+s)):(l+s - (l*s));
	   float p = (2.0f * l) - q;
	   float Hk = h/360.0f;
	   float T[3];
	   T[0] = Hk + 0.3333333f; // Tr  0.3333333f=1.0/3.0
	   T[1] = Hk;             // Tb
	   T[2] = Hk - 0.3333333f; // Tg

	   for(int i=0; i<3; i++)
	   {
		   if(T[i] < 0) T[i] += 1.0f;
		   if(T[i] > 1) T[i] -= 1.0f;

		   if((T[i]*6) < 1)
		   {
			   T[i] = p + ((q-p)*6.0f*T[i]);
		   }
		   else if((T[i]*2.0f) < 1) //(1.0/6.0)<=T[i] && T[i]<0.5
		   {
			   T[i] = q;
		   }
		   else if((T[i]*3.0f) < 2) // 0.5<=T[i] && T[i]<(2.0/3.0)
		   {
			   T[i] = p + (q-p) * ((2.0f/3.0f) - T[i]) * 6.0f;
		   }
		   else T[i] = p;
	   }
	   R = T[0]*255.0f;
	   G = T[1]*255.0f;
	   B = T[2]*255.0f;

   }
   rgb->red = (uint8_t)((R>255)? 255 : ((R<0)?0 : R));
   rgb->green = (uint8_t)((G>255)? 255 : ((G<0)?0 : G));
   rgb->blue = (uint8_t)((B>255)? 255 : ((B<0)?0 : B));

}
//int _tmain(int argc, _TCHAR* argv[])
//{
//   COLOR_RGB  rgb={254, 216, 166};
//   COLOR_HSL  hsl;
//   RGBtoHSL(&rgb, &hsl);
//   printf("H=%.0f; S=%.0f; L=%.0fn", hsl.hue, hsl.saturation, hsl.luminance);
//   HSLtoRGB(&hsl, &rgb);
//   RGBtoHSL(&rgb, &hsl);
//   printf("H=%.0f; S=%.0f; L=%.0fn", hsl.hue, hsl.saturation, hsl.luminance);
//   getchar();
//    return 0;
//
//}
//
//void RGB2HSV( uint16_t * h, uint16_t * s, uint16_t * v, uint8_t r, uint8_t g, uint8_t b)
//{
//    double rr, gg, bb;
//    double hh, ss, vv;
//    double cmax, cmin, cdes;
//
//    rr = r;
//    gg = g;
//    bb = b;
//
//    cmax = (rr > gg) ? rr : gg;
//    if (bb > cmax) {
//        cmax = bb;
//    }
//
//    cmin = (rr < gg) ? rr : gg;
//    if (bb < cmin) {
//        cmin = bb;
//    }
//
//    cdes = cmax - cmin;
//    vv = cmax;
//    if (cdes != 0) {
//        ss = cdes * SCALE / cmax;
//        if (cmax == rr) {
//            hh = (gg - bb) * SCALE / cdes;
//        }else if (cmax == gg) {
//            hh = (bb - rr) * SCALE / cdes + 2 * H_SCALE;
//        }else {
//            hh = (rr - gg) * SCALE / cdes + 4 * H_SCALE;
//        }
//    }else if (cmax != 0) {
//        ss = cdes * SCALE / cmax;
//        hh = 0;
//    }else {
//        ss = 0;
//        hh = 0;
//    }
//    if (hh < 0) {
//        hh += 6 * H_SCALE;
//    }
//
//    *h = hh * H_GETA;
//    *s = ss * H_GETA;
//    *v = vv * H_GETA;
//}
//
//void HSV2RGB( uint8_t *r, uint8_t *g, uint8_t *b, uint16_t h, uint16_t s, uint16_t v)
//{
//    double rr = 0, gg = 0, bb = 0;
//    double hh, ss, vv;
//
//    if (h == 6 * H_GETA * H_SCALE) {
//        h = 0;
//    }
//    hh = (double)h / H_GETA;
//    ss = (double)s / GETA;
//    vv = (double)v / GETA;
//
//    switch((int)(hh / H_SCALE)) {
//        case 0:
//            rr = SCALE;
//            gg = hh;
//            bb = 0;
//            break;
//        case 1:
//            rr = 2 * H_SCALE - hh;
//            gg = SCALE;
//            bb = 0;
//            break;
//        case 2:
//            rr = 0;
//            gg = SCALE;
//            bb = hh - 2 * H_SCALE;
//            break;
//        case 3:
//            rr = 0;
//            gg = 4 * H_SCALE - hh;
//            bb = SCALE;
//            break;
//        case 4:
//            rr = hh - 4 * H_SCALE;
//            gg = 0;
//            bb = SCALE;
//            break;
//        case 5:
//            rr = SCALE;
//            gg = 0;
//            bb = 6 * H_SCALE - hh;
//            break;
//    }
//
//    rr = (rr + (SCALE - rr) * (SCALE - ss) / SCALE) * vv / SCALE;
//    gg = (gg + (SCALE - gg) * (SCALE - ss) / SCALE) * vv / SCALE;
//    bb = (bb + (SCALE - bb) * (SCALE - ss) / SCALE) * vv / SCALE;
//
//    *r = rr;
//    *g = gg;
//    *b = bb;
//    if (*r > 255)*r = 255;
//    if (*g > 255)*g = 255;
//    if (*b > 255)*b = 255;
//}
//
//void RGB2HLS( double *h, double *l, double *s, uint8_t r, uint8_t g, uint8_t b)
//{
//    double dr = (double)r/255;
//    double dg = (double)g/255;
//    double db = (double)b/255;
//    double cmax = MAX(dr, MAX(dg, db));
//    double cmin = MIN(dr, MIN(dg, db));
//    double cdes = cmax - cmin;
//    double hh, ll, ss;
//
//    ll = (cmax+cmin)/2;
//    if(cdes){
//        if(ll <= 0.5)
//            ss = (cmax-cmin)/(cmax+cmin);
//        else
//            ss = (cmax-cmin)/(2-cmax-cmin);
//
//        if(cmax == dr)
//            hh = (0+(dg-db)/cdes)*60;
//        else if(cmax == dg)
//            hh = (2+(db-dr)/cdes)*60;
//        else// if(cmax == b)
//            hh = (4+(dr-dg)/cdes)*60;
//        if(hh<0)
//            hh+=360;
//    }else
//        hh = ss = 0;
//
//    *h = hh;
//    *l = ll;
//    *s = ss;
//}
//
//void HLS2RGB( uint8_t *r, uint8_t *g, uint8_t *b, double h, double l, double s)
//{
//    double cmax,cmin;
//
//    if(l <= 0.5)
//        cmax = l*(1+s);
//    else
//        cmax = l*(1-s)+s;
//    cmin = 2*l-cmax;
//
//    if(s == 0){
//        *r = *g = *b = l*255;
//    }else{
//        *r = HLS2RGBvalue(cmin,cmax,h+120)*255;
//        *g = HLS2RGBvalue(cmin,cmax,h)*255;
//        *b = HLS2RGBvalue(cmin,cmax,h-120)*255;
//    }
//}
//
//double HLS2RGBvalue(double n1,double n2, double hue)
//{
//    if(hue > 360)
//        hue -= 360;
//    else if(hue < 0)
//        hue += 360;
//    if(hue < 60)
//        return n1+(n2-n1)*hue/60;
//    else if(hue < 180)
//        return n2;
//    else if(hue < 240)
//        return n1+(n2-n1)*(240-hue)/60;
//    else
//        return n1;
//}
